home *** CD-ROM | disk | FTP | other *** search
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Cumulate Draw SVG Renderer.
- *
- * The Initial Developer of the Original Code is
- * Cumulate Labs Inc.
- * Portions created by Cumulate Labs Inc. are Copyright (C) 2006-2007
- * Cumulate Labs Inc. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
- /*----------------------------------------------------------------------------
- SVGRENDERER 0.1
- SVG Renderer For cumulate draw (http://www.cumulatelabs.com)
- History:
- 2006-10-19 | created
- */
-
- /**********************************BEGIN INITIALIZATION FUNCTIONS******************************/
- function SVGRenderer() {
- this.base = AbstractRenderer;
- this.svgRoot = null;
- }
-
-
- SVGRenderer.prototype = new AbstractRenderer;
-
-
- SVGRenderer.prototype.init = function(elem) {
- this.MAX_HEIGHT=2000;
- this.MAX_WIDTH=2000;
- this.COORD_X=1000;//ALL shapes are defined in 1000x1000 coord space
- this.COORD_Y=1000;
- this.CONNECTOR_TAG="svg:connector";
- this.TEXT_TEMPLATE_PREFIX="text:template";
- this.LINE_DELIMITER="\n";
- this.GRADIENT_PREFIX="GRADIENT";
- this.MARKER_BEGIN_PREFIX="MARKER_START";
- this.MARKER_END_PREFIX="MARKER_END";
- this.EXTENSION='fmd';
- this.TYPE="SVG";
- this.container = elem;
- this.svgNamespace = 'http://www.w3.org/2000/svg';
- this.cumulateNamespace="urn:schemas-cumulatelabs-com:svg";
- this.xmlNamespace="http://www.w3.org/2001/xml";
- this.svgRoot = this.container.ownerDocument.createElementNS(this.svgNamespace, "svg");
- this.svgRoot.setAttribute("xml:space","preserve");
- this.LONG_DASH="7,3";
- this.SHORT_DASH="4,3";
- var shadow=this.loadShape('shadow','defs');
-
- this.svgRoot.style.position="absolute";
- this.svgRoot.style.zIndex=10;
- this.svgRoot.setAttributeNS(null, 'x','0px');
- this.svgRoot.setAttributeNS(null, 'y', '0px');
- this.svgRoot.setAttributeNS(null, 'width',this.MAX_WIDTH+'px');
- this.svgRoot.setAttributeNS(null, 'height',this.MAX_HEIGHT+'px');
-
- var firstChild=this.container.firstChild;
- this.svgRoot.style.MozUserSelect = 'none';
- this.minIndex=200;
- this.maxIndex=200;
- this.container.insertBefore(this.svgRoot,firstChild);
- this.svgRoot.appendChild(shadow);
-
- }
-
- /****************************************************END INITIALIZATION FUNCTIONS**************************************/
-
- /**
- *return the current bounds of the shape
- **/
- SVGRenderer.prototype.bounds = function(shape) {
- if(!shape)return
- var rect = { x:0, y:0, width:0, height: 0,rotation:0,x2:0,y2:0,id:0,type:"",controlX:0,controlY:0,controlX2:0,controlY2:0 };
- rect['id']=shape.getAttributeNS(null,"id");
- if(this.isConnector(shape))
- {
- rect['x']=this.getConnectorFromX(shape);
- rect['y']=this.getConnectorFromY(shape);
- rect['x2']=this.getConnectorToX(shape);
- rect['y2']=this.getConnectorToY(shape);
- rect['type']=this.getConnectorType(shape);
- if(rect.type=='curve-line'){
- var obj1=this.getControl1(shape);
- var obj2=this.getControl2(shape);
- rect['controlX']=obj1.x;
- rect['controlY']=obj1.y;
- rect['controlX2']=obj2.x;
- rect['controlY2']=obj2.y;
- }
-
- }
- else{
- rect['rotation']=this.getRotation(shape);
- if(!rect['rotation'])
- rect['rotation']=0;
- rect['x'] = this.getX(shape);
- rect['y'] = this.getY(shape);
- rect['width'] = this.getWidth(shape);
- rect['height'] = this.getHeight(shape);
-
- }
- return rect;
- }
-
- /*************************BEGIN SHAPE CREATION FUNCTIONS****************************/
- /**
- *load an xml shape for creation-
- *TODO we will have to add some error handling later on
- */
-
- SVGRenderer.prototype.loadShape=function(shapeID,retrieveTag){
- objValidXMLFile=this.loadXML("shapes/svg/"+shapeID+".xml");
- var nodeList=objValidXMLFile.getElementsByTagName(retrieveTag);
- if(retrieveTag){
- var node=nodeList[0];
- return node;
- }
-
- }
- SVGRenderer.prototype.loadXML=function(path){
- var objValidXMLFile = document.implementation.createDocument(null, null, null);
- objValidXMLFile.async=false;
- objValidXMLFile.load(path);
- return objValidXMLFile;
-
- }
- /**
- * create a line shape
- **/
- SVGRenderer.prototype.createLine=function(shape,lineColor,lineWidth,left,top,lineStyle){
-
- var svg=this.loadShape(shape,"g");
- this.svgRoot.appendChild(svg);
- if(shape=='line'||shape=='curve-line'){
- this.setLineFrom(svg,left,top);
- this.setLineTo(svg,left,top);
- }
- if(shape=='curve-line'){
- this.setControl1(svg,left,top);
- this.setControl2(svg,left,top);
- }
- var markers=this.getMarkers(svg);
- markers[0].id=this.MARKER_BEGIN_PREFIX+createUUID();
- markers[1].id=this.MARKER_END_PREFIX+createUUID();
- this.setZIndex(svg,this.maxIndex++);
-
- return svg;
- }
-
- /**
- *all svg shapes are in the format g/svg/path in addition filters for linear gradient, line stroke may be added
- **/
- SVGRenderer.prototype.create = function(shape, fillColor, lineColor, lineWidth, left, top, width, height) {
- var svg=this.loadShape(shape,"g");
- this.svgRoot.appendChild(svg);
- this.setX(svg,left);
- this.setY(svg,top);
- this.setWidth(svg,width);
- this.setHeight(svg,height);
- this.setZIndex(svg,this.maxIndex++);
- this.fixLinearGradientID(svg);
- //now fix the shape to match its linear gradient!
- // var isGradient=this.getLinearGradient(svg);
- // if(isGradient)this.setLinearGradient(svg,true);
- // this.setFillColor(svg,this.getFillColor(svg));
-
-
- return svg;
- };
- /**
- *utility function to create and element based on namespace constants
- **/
- SVGRenderer.prototype.createElement=function(elementTag,namespace){
- if(namespace=='CUMULATE_LABS'){
- return this.container.ownerDocument.createElementNS(this.cumulateNamespace,elementTag);
- }
- else{
- return this.container.ownerDocument.createElementNS(this.svgNamespace,elementTag);
- }
-
-
- }
-
- /**
- * a utitlity function to return an attribute in IE specific manner,assumes that element
- * is not null!
- **/
- SVGRenderer.prototype.getAttribute=function(element,attribute){
- return element.getAttributeNS(null,attribute);
-
- }
-
- /**
- * clone the node
- **/
- SVGRenderer.prototype.copy=function(shape){
- if(!shape)return null;
- return shape.cloneNode(true);
-
- }
-
- /**
- *add the cloned node
- **/
- SVGRenderer.prototype.paste=function(shape){
- if(!shape)return;
- var node=shape;
- node.id='shape:' + createUUID();
- var svg=node.getElementsByTagName("svg");
- if(svg.length>0)
- svg.item(0).id='shape:'+createUUID();
- var text=node.getElementsByTagName("text")
- for(var i=0;i<text.length;i++){
- var textItem=text.item(i);
- if(textItem.id.indexOf(this.TEXT_TEMPLATE_PREFIX)>=0){
- textItem.id=this.TEXT_TEMPLATE_PREFIX+node.id;
- }
- }
-
- if(!this.isConnector(node)){
- var x=this.getX(node);
- var y=this.getY(node);
- this.setX(node,(x*1)+10);
- this.setY(node,(y*1)+10);
- //update the gradient;
- this.fixLinearGradientID(node);
- }
- if(this.isConnector(node)){
- var markers=this.getMarkers(node);
- markers[0].id=this.MARKER_BEGIN_PREFIX+createUUID();
- markers[1].id=this.MARKER_END_PREFIX+createUUID();
- var lineStyle=this.getLineStyle(node);
- this.setLineStyle(node,lineStyle);
-
- }
- //now null any connections
- var connectList=node.getElementsByTagName("connection");
- var array=new Array();
- for(var i=0;i<connectList.length;i++){
- //if its a line emtpy it
- if(this.isConnector(node)){
- connectList.item(i).setAttribute("shapeid","xx");
- connectList.item(i).setAttribute("shapepoint","-1");
- }
- //if its a shape remove it!
- else{
- array[i]=connectList.item(i);
- }
- }
- for(var i=0;i<array.length;i++){
- this.remove(array[i]);
- }
- //append automatically brings the shape to the front for svg
- this.svgRoot.appendChild(node);
- return node;
- }
-
-
- /*************************END SHAPE CREATION FUNCTIONS****************************/
- /**
- *indicate if a shape is a connector
- **/
- SVGRenderer.prototype.isConnector=function(shape){
- if(shape)
- return (shape.getElementsByTagName("connector").length>0);
- else
- return false;
- }
-
- /*************************ZINDEX FUNCTIONS************************/
- /**
- *set the shape ZIndex, this method does nothing since svg does not support zindexes
- *@see http://wiki.svg.org/Rendering_Order
- *@param shape
- *@param zIndex;
- **/
- SVGRenderer.prototype.setZIndex=function(shape,zIndex){
- if(shape){
- shape.setAttributeNS(null,"z-index",zIndex);
- }
- }
- /**
- *get the shape zIndex, this method is just informational, since svg does not support zindexes
- *@see http://wiki.svg.org/Rendering_Order
- *@param shape
- *@return zIndex
- **/
- SVGRenderer.prototype.getZIndex=function(shape){
- if(shape)
- return shape.getAttributeNS(null,"z-index");
- }
-
- /**
- * send to back
- *@param the shape
- **/
- SVGRenderer.prototype.sendToBack=function(shape){
- if(shape){
- var node =shape.cloneNode(true);
- this.remove(shape);
- this.svgRoot.insertBefore(node,this.svgRoot.firstChild);
- this.setZIndex(node,this.minIndex--);
- return node;
- }
- }
-
- /**
- * Bring to Front
- *@param the shape
- **/
- SVGRenderer.prototype.bringToFront=function(shape){
- if(shape){
- var node =shape.cloneNode(true);
- this.remove(shape);
- this.svgRoot.appendChild(node);
- this.setZIndex(node,this.maxIndex++);
- return node;
- }
- }
-
- /*************************LINE FUNCTIONS***********************/
- /**
- *set the line from
- **/
- SVGRenderer.prototype.setLineFrom=function(shape,fromX,fromY){
- var subject=this.getShapeSubject(shape);
- var type=this.getConnectorType(shape);
- if(type=='line'){
- subject.setAttributeNS(null,"x1",fromX);
- subject.setAttributeNS(null,"y1",fromY);
- }
- else if(type=='curve-line'){
- var path=subject.pathSegList;
- var pathItem=path.getItem(0);
- pathItem.x=fromX;
- pathItem.y=fromY;
- }
-
-
- }
- /**
- *set the line to
- **/
- SVGRenderer.prototype.setLineTo=function(shape,toX,toY){
- var subject=this.getShapeSubject(shape);
- var type=this.getConnectorType(shape);
- if(type=='line'){
- subject.setAttributeNS(null,"x2",toX);
- subject.setAttributeNS(null,"y2",toY);
- }
- else if(type=='curve-line'){
- var path=subject.pathSegList;
- var pathItem=path.getItem(1);
- pathItem.x=toX;
- pathItem.y=toY;
- }
-
- }
- /**
- * set control point 1
- **/
- SVGRenderer.prototype.setControl1=function(shape,toX,toY){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- var pathItem=path.getItem(1);
- pathItem.x1=toX;
- pathItem.y1=toY;
-
-
- }
-
- /**
- * set control point 1
- **/
- SVGRenderer.prototype.getControl1=function(shape){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- var pathItem=path.getItem(1);
- var obj=new Object();
- obj.x=pathItem.x1;
- obj.y=pathItem.y1;
- return obj;
-
- }
-
-
- /**
- * set control point 1
- **/
- SVGRenderer.prototype.setControl2=function(shape,toX,toY){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- var pathItem=path.getItem(1);
- pathItem.x2=toX;
- pathItem.y2=toY;
-
-
- }
-
- /**
- * set control point 1
- **/
- SVGRenderer.prototype.getControl2=function(shape){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- var pathItem=path.getItem(1);
- var obj=new Object();
- obj.x=pathItem.x2;
- obj.y=pathItem.y2;
- return obj;
-
- }
-
-
-
-
- /**
- *simply for compatibility reasons, the vml version converts pixels to points in this method,
- *svg version does not need that
- **/
- SVGRenderer.prototype.moveLinePoint=function(shape,toX,toY,isFrom){
- this.moveLine(shape,toX,toY,isFrom);
- }
- /**
- *move line or polyline
- **/
- SVGRenderer.prototype.moveLine=function(shape,toX,toY, isFrom){
- if(!shape||!this.isConnector(shape)){
- return;
- }
- var type=this.getConnectorType(shape);
- if(type=='line'||type=='curve-line'){
- if(isFrom){
- this.setLineFrom(shape,toX,toY);
- }
- else{
- this.setLineTo(shape,toX,toY);
- }
- }
- else{
- var subject =shape.getElementsByTagName("polyline")[0];
- var points=subject.points;
- var length=points.numberOfItems;
- if(isFrom){
-
- var x=points.getItem(length-1).x;
- var y=points.getItem(length-1).y;
- this.drawOrthoLine(shape,toX,toY,x,y);
- }
- else{
- var x=points.getItem(0).x;
- var y=points.getItem(0).y;
- this.drawOrthoLine(shape,x,y,toX,toY);
- }
- }
-
- }
- /**********************************************BEGIN ORTHO-LINE DRAW FUNCTIONS**************************/
- /**
- * get the segments of the orthogonal connector--get the central segment,
- * @return {object} containing x,y,x2,y2
- */
- SVGRenderer.prototype.getOrthoLineCenterSegment=function(shape){
- //debugger;
- var obj=new Object();
- var points=this.getShapeSubject(shape).points;
-
- //get the center point
- var centerPoint=Math.round(points.numberOfItems/2-1);
- var center=points.getItem(centerPoint);
- var before=points.getItem(centerPoint-1);
- var after=points.getItem(centerPoint+1);
- var distanceA=((center.y-before.y)*(center.y-before.y))+((center.x-before.x)*(center.x-before.x));
- var distanceB=((center.y-after.y)*(center.y-after.y))+((center.x-after.x)*(center.x-after.x));
- var referencePoint=distanceA>distanceB?before:after;
- obj.x=referencePoint.x;
- obj.y=referencePoint.y;
- obj.x2=center.x;
- obj.y2=center.y;
- return obj;
- }
- /*
- *special method to draw orthogonal lines. first calculate the horizontal distance, then calculate the vertical distance,
- * if horizontal< vertical, split horizontal in 1/2 and vice versa, set this in the shape
- */
- SVGRenderer.prototype.drawOrthoLine= function(shape,fromX,fromY,toX,toY){
- var path=this.calculateOrthoLinePath(shape,fromX,fromY,toX,toY);
- var polyline=this.getShapeSubject(shape);
- polyline.setAttributeNS(null,"points",path);
- }
-
-
-
- /************************************************END ORTHO-LINE DRAW FUNCTIONS************************/
- /**
- *display all connection points, this will take the c:connection-point coordinates defined in 1000,1000 space
- * and scale them to current coordinate system
- **/
- SVGRenderer.prototype.showConnectionPoints=function(shape){
- if(!shape)return;
- //debugger;
- var rect=this.bounds(shape);
- var rotation=rect['rotation'];
- if(!rotation)rotation=0;
- this.remove($('active-shape-tracker'));
- var doc=this.container.ownerDocument;
- var group=doc.createElementNS(this.svgNamespace,"g");
- var svg=doc.createElementNS(this.svgNamespace,"svg");
- group.appendChild(svg);
- group.style.position="ABSOLUTE";
- group.style.zIndex=this.maxIndex+1;
- var centerX=parseInt(rect['x'])+parseInt(rect['width']/2);
- var centerY=parseInt(rect['y'])+parseInt(rect['height']/2);
- group.setAttributeNS(null,"transform","rotate("+rotation+","+centerX+","+centerY+")");
- group.style.zIndex=(shape.style.zIndex*1)+1;
- group.id='active-shape-tracker';
- var width=rect['width'];
- var height=rect['height'];
- var nodeList=shape.getElementsByTagName("connection-point");
- for(var i=0;i<nodeList.length;i++){
- var node=nodeList.item(i);
- var oval=doc.createElementNS(this.svgNamespace,"circle");
- var x=parseInt(rect['x'])+(node.getAttribute('x')*width/this.COORD_X);
- var y=parseInt(rect['y'])+(node.getAttribute('y')*height/this.COORD_Y);
- oval.setAttributeNS(null,'fill',"red");
- oval.setAttributeNS(null,'stroke',"black");
- oval.style.position="ABSOLUTE";
- oval.setAttributeNS(null,"cx",x);
- oval.setAttributeNS(null,"cy",y);
- oval.setAttributeNS(null,"r","3");
- svg.appendChild(oval);
- }
- this.svgRoot.appendChild(group);
- }
-
- /*
- *connectLine, first calculate if the line end matches a connection point
- * if yes then add an entry to ensure that line and shape are connected
- **/
- SVGRenderer.prototype.connectLine=function(shape,connector,toOrFrom){
-
- if(!connector)return;
- //first disconnect the line
- this.disconnectLineFromShape(connector,toOrFrom);
- if(!shape)return;
- //get the line coordinates in pixels
- var screenxdpi=screen.logicalXDPI / 72;
- var x=0;
- var y=0;
- var type=this.getConnectorType(connector);
- if(type=='line'||type=='curve-line'){
- var line=this.getShapeSubject(connector);
- if(toOrFrom=="from"){
- x=this.getConnectorFromX(connector);
- y=this.getConnectorFromY(connector);
- }
- else{
- x=this.getConnectorToX(connector);
- y=this.getConnectorToY(connector);
- }
- }
- else{
- if(toOrFrom=="from"){
- x=this.getShapeSubject(connector).points.getItem(0).x;
- y=this.getShapeSubject(connector).points.getItem(0).y;
-
- }
- else{
- var length=this.getShapeSubject(connector).points.numberOfItems;
- if(length==0)return;
- x=this.getShapeSubject(connector).points.getItem(length-1).x;
- y=this.getShapeSubject(connector).points.getItem(length-1).y;
- }
-
- }
- //now get the shape center
- var rect=this.bounds(shape);
- var centerX=parseInt(rect['x']*1)+parseInt(rect['width']/2);
- var centerY=parseInt(rect['y']*1)+(rect['height']/2);
- //get the rotation
- var rotation=rect['rotation'];
- if(!rotation)rotation=0;
- //get the shape coordinate size, hardcode for now
-
-
- var connectionList=shape.getElementsByTagName("connection-point");
- for(var i=0;i<connectionList.length;i++){
- var node=connectionList.item(i);
- //for each connection point get its(unrotated) pixel location
- var conX=(rect['x']*1)+((node.getAttributeNS(null,"x")/this.COORD_X)*rect['width']);
- var conY=(rect['y']*1)+((node.getAttributeNS(null,"y")/this.COORD_Y)*rect['height']);
- //now translate the center to the origin
- conX=conX-centerX;
- conY=conY-centerY;
- //now rotate and translate back
- var finalX=((conX*Math.cos((Math.PI/180)*(rotation)))-(conY*Math.sin((Math.PI/180)*(rotation)))*1)+(centerX*1);
- var finalY=((conX*Math.sin((Math.PI/180)*(rotation)))+(conY*Math.cos((Math.PI/180)*(rotation)))*1)+(centerY*1);
-
- if(x>(finalX-4)&&x<((finalX*1)+4)&&y>(finalY-4)&&y<((finalY*1)+4)){
- this.connectLineToShape(shape,connector,toOrFrom,node,i);
- var isFrom=(toOrFrom=="from")?true:false;
- this.moveLine(connector,finalX,finalY,isFrom);
- $('help').innerHTML="Connected line to shape";
- //no need to go on, we found our connection point
- return;
- }
-
- }
- }
-
- /******************************END LINE FUNCTIONS********************************/
- /*******************************BEGIN SHAPE ATTRIBUTE GETTERS AND SETTERS************/
-
- /**
- *return the type of this connector
- **/
- SVGRenderer.prototype.getConnectorType=function(shape){
- return shape.getAttributeNS(null,"type");
-
-
- }
- /**
- *get from x for a valid connector
- **/
- SVGRenderer.prototype.getConnectorFromX=function(shape){
- var x1=null;
- var type=this.getConnectorType(shape);
- if(type=='line'){
- x1=this.getShapeSubject(shape).getAttributeNS(null,"x1");
- }
- else if(type=='curve-line'){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- x1=path.getItem(0).x;
- }
- else{
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- if(points.numberOfItems>0)
- x1=points.getItem(0).x;
- }
- return x1;
- }
- /**
- *get from y for a valid connector
- **/
- SVGRenderer.prototype.getConnectorFromY=function(shape){
- var y1=null;
- var type=this.getConnectorType(shape);
- if(type=='line'){
- y1=this.getShapeSubject(shape).getAttributeNS(null,"y1");
-
- }
- else if(type=='curve-line'){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- y1=path.getItem(0).y;
- }
- else{
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- if(points.numberOfItems>0)
- y1=points.getItem(0).y;
-
- }
- return y1;
- }
- /**
- *get to x for a valid connector
- **/
- SVGRenderer.prototype.getConnectorToX=function(shape){
- var x2=null;
- var type=this.getConnectorType(shape);
- if(type=='line'){
- x2=this.getShapeSubject(shape).getAttributeNS(null,"x2");
- }
- else if(type=='curve-line'){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- x2=path.getItem(1).x;
- }
- else{
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- var length=points.numberOfItems;
- if(length==0)return null;
- x2=points.getItem(length-1).x;
-
- }
- return x2;
- }
- /**
- *get to y for a valid connector
- **/
-
- SVGRenderer.prototype.getConnectorToY=function(shape){
- var y2;
- var type=this.getConnectorType(shape);
- if(type=='line'){
- y2=this.getShapeSubject(shape).getAttributeNS(null,"y2");
- }
- else if(type=='curve-line'){
- var subject=this.getShapeSubject(shape);
- var path=subject.pathSegList;
- y2=path.getItem(1).y;
- }
- else{
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- var length=points.numberOfItems;
- if(length==0)return;
- y2=points.getItem(length-1).y;
- }
- return y2;
- }
-
- /**
- *get all shape objects (not including connectors)!
- **/
- SVGRenderer.prototype.getAllShapes=function(doc){
- var nodes=doc.getElementsByTagName("g");
- var array=new Array();
- for (var i=0;i<nodes.length;i++){
- if(!this.isConnector(nodes[i])){
- array[array.length]=nodes[i];
- }
- }
- return array;
- }
-
- /**
- *get all connectors (but not shapes)
- **/
- SVGRenderer.prototype.getAllConnectors=function(doc){
- var nodes=doc.getElementsByTagName("g");
- var array=new Array();
- for (var i=0;i<nodes.length;i++){
- if(this.isConnector(nodes[i])){
- array[array.length]=nodes[i];
- }
- }
- return array;
- }
- /**
- *get the stroke width of the shape,
- **/
- SVGRenderer.prototype.getStrokeWidth=function(shape){
- if(!shape)return null;
- return this.getShapeSubject(shape).getAttributeNS(null,"stroke-width");
-
- }
-
- /**
- *set the stroke width of the shape,
- **/
- SVGRenderer.prototype.setStrokeWidth=function(shape,width){
- this.getShapeSubject(shape).setAttributeNS(null,"stroke-width",width);
-
- }
-
- /**
- *get the line color
- **/
- SVGRenderer.prototype.getLineColor=function(shape){
- return this.getShapeSubject(shape).getAttributeNS(null,"stroke");
-
- }
-
- /**
- *set the line color
- **/
- SVGRenderer.prototype.setLineColor=function(shape,value){
- if(value=='')value='none';
- this.getShapeSubject(shape).setAttributeNS(null, 'stroke', value);
- if(this.isConnector(shape)){
- var markers=this.getMarkers(shape);
- markers[0].setAttributeNS(null,"stroke",value);
- markers[0].setAttributeNS(null,"fill",value);
- markers[1].setAttributeNS(null,"stroke",value);
- markers[1].setAttributeNS(null,"fill",value);
-
- }
- }
-
- /**
- *get the line color
- **/
- SVGRenderer.prototype.getOpacity=function(shape){
- return this.getShapeSubject(shape).getAttributeNS(null,"fill-opacity");
-
- }
-
- /**
- *set the line color
- **/
- SVGRenderer.prototype.setOpacity=function(shape,value){
- if (value != '')
- this.getShapeSubject(shape).setAttributeNS(null, 'fill-opacity', value);
- }
-
-
- /**
- *get the fill color
- **/
- SVGRenderer.prototype.getFillColor=function(shape){
- if(!this.isConnector(shape)){
- if(!this.getLinearGradient(shape))
- return this.getShapeSubject(shape).getAttributeNS(null,"fill");
- else{
- var gradient=this.getLinearGradientElement(shape);
- var stop=gradient.getElementsByTagName("stop")[0];
- return stop.getAttributeNS(null,"stop-color");
- }
- }
- }
-
- /**
- *set the fill color
- **/
- SVGRenderer.prototype.setFillColor=function(shape,value){
- if(this.isConnector(shape))return;
- if(value=='') value='none';
- var gradient=this.getLinearGradientElement(shape);
- var stop=gradient.getElementsByTagName("stop")[0];
- stop.setAttributeNS(null,'stop-color',value);
- var isGradient=this.getLinearGradient(shape);
- if(!isGradient)
- this.getShapeSubject(shape).setAttributeNS(null, 'fill', value);
- }
-
- /**
- * set the shadow for the shape even though it does not work in firefox 1.5, it should work in 2.0 and above
- **/
- SVGRenderer.prototype.setShadow=function(shape,value){
- if (value != 'false')
- this.getShapeSubject(shape).setAttributeNS(null, 'filter',"url(#shadow_filter)" );
- else
- this.getShapeSubject(shape).setAttributeNS(null, 'filter', '');
- }
-
- SVGRenderer.prototype.getShadow=function(shape){
- if(!shape)return false;
- var value=this.getShapeSubject(shape).getAttributeNS(null,'filter');
- return(value=="url(#shadow_filter)");
-
-
- }
-
- /**
- *get the actual element that represents the linear gradient
- **/
-
- SVGRenderer.prototype.getLinearGradientElement=function(shape){
- var gradientList=shape.getElementsByTagName("linearGradient");
- if(gradientList.length>0)return gradientList[0];
- else return null;
- }
-
- /**
- * set the linear gradient
- **/
- SVGRenderer.prototype.setLinearGradient=function(shape, value){
- if(this.isConnector(shape))return;
- var subject=this.getShapeSubject(shape);
- var gradient=this.getLinearGradientElement(shape);
- if(value){
- var idURL="url(#"+gradient.id+")";
- subject.setAttributeNS(null,"fill",idURL);
- }
- else{
- var stop=gradient.getElementsByTagName("stop")[0];
- var color=stop.getAttributeNS(null,"stop-color");
- subject.setAttributeNS(null,"fill",color);
- }
- }
- /**
- *return true or false indicating if the linear gradient is set
- **/
- SVGRenderer.prototype.getLinearGradient=function(shape){
- var subject=this.getShapeSubject(shape);
- var gradient=subject.getAttributeNS(null,"fill");
- return(gradient.indexOf("url")>=0);
-
-
- }
-
- /**
- * this method is called during create or paste. The idea is to provide unique id's for all
- * linear gradients and match them to the corresponding paths
- */
- SVGRenderer.prototype.fixLinearGradientID=function(shape){
- //first get all the linear gradients
- var gradients=shape.getElementsByTagName("linearGradient");
- var subShapes=this.getAllSubShapes(shape);
- for(var i=0;i<gradients.length;i++){
- var gradient=gradients.item(i);
- var gradientId=gradient.id;
- var newGradientId="Gradient0"+(i+1)+createUUID();
- gradient.id=newGradientId;
- for(var j=0;j<subShapes.length;j++){
- var subShape=subShapes.item(j);
- if("url(#"+gradientId+")"==subShape.getAttributeNS(null,"fill")
- ||"url("+gradientId+")"==subShape.getAttributeNS(null,"fill")){
- subShape.setAttributeNS(null,"fill","url(#"+newGradientId+")");
- }
- }
-
- }
- }
-
- /**
- *return the marker elements
- **/
- SVGRenderer.prototype.getMarkers=function(shape){
- return shape.getElementsByTagName("marker");
- }
-
- /**
- *setLineStyle
- *@param shape
- *@param style: arrow-both, arrow-from, arrow-to, none
- **/
- SVGRenderer.prototype.setLineStyle=function(shape,style){
- if(!this.isConnector(shape))return;
- var markers=this.getMarkers(shape);
- var idStart="";
- var idEnd="";
- if(style=='arrow-from'||style=='arrow-both'){
-
- idStart=markers[1].id;
- }
-
- if(style=='arrow-to'||style=='arrow-both'){
-
- idEnd=markers[0].id
- }
- if(idStart.length>0){
- idStart="url(#"+idStart+")";
- }
- if(idEnd.length>0){
- idEnd="url(#"+idEnd+")";
- }
- var subject=this.getShapeSubject(shape);
- subject.setAttributeNS(null,"marker-start",idStart);
- subject.setAttributeNS(null,"marker-end",idEnd);
-
-
- }
- /**
- *getLineStyle
- **/
- SVGRenderer.prototype.getLineStyle=function(shape){
- if(!this.isConnector(shape))return '';
- var subject=this.getShapeSubject(shape);
- var markerEnd=subject.getAttributeNS(null,"marker-end");
- var markerStart=subject.getAttributeNS(null,"marker-start");
- if(markerEnd.length>0&&markerStart.length>0)
- return "arrow-both";
- else if(markerEnd.length==0&&markerStart.length>0)
- return "arrow-from";
- else if(markerEnd.length>0&&markerStart.length==0)
- return "arrow-to";
- else
- return "none";
-
- }
- /**
- * get the line dash style
- * @return one of -"solid", "short-dash","long-dash"
- */
- SVGRenderer.prototype.getLineDashStyle=function(shape){
- var subject=this.getShapeSubject(shape);
- var dashStyle=subject.getAttributeNS(null,"stroke-dasharray");
- if(!dashStyle||dashStyle=="")return "solid";
- else if(dashStyle==this.LONG_DASH)return "long-dash";
- else return "short-dash";
- }
-
- /**
- * set the line dash style, we will set this on all
- */
- SVGRenderer.prototype.setLineDashStyle=function(shape,style){
- if(style=="long-dash")style=this.LONG_DASH;
- else if(style=="short-dash")style=this.SHORT_DASH;
- else style="";
- if(this.isConnector(shape)){
- var subject=this.getShapeSubject(shape);
- subject.setAttributeNS(null,"stroke-dasharray",style)
- }
- else{
- var subShapes=this.getAllSubShapes(shape)
- for(var i=0;i<subShapes.length;i++){
- subShapes[i].setAttributeNS(null,"stroke-dasharray",style);
- }
- }
- }
- /**
- *this method will return the actual subject of a shape, the subject could either be a path or line,polyline in case
- of connectors, this assumes that the shape has only one subject
- **/
- SVGRenderer.prototype.getShapeSubject=function(shape){
- if(!shape)return null;
- if(this.isConnector(shape)){
- var type=this.getConnectorType(shape);
- if(type=='line')
- return shape.getElementsByTagName('line')[0];
- else if(type=='ortho-line')
- return shape.getElementsByTagName('polyline')[0];
- else if(type=='curve-line')
- return shape.getElementsByTagName('path')[0];
- }
- else if(shape.getElementsByTagName("path").length>0){
- return shape.getElementsByTagName("path")[0];
- }
- //otherwise its a primitive shape e.g rect
- else{
- return shape;
- }
- }
- /**
- * return all the subshapes for a given shape
- * @param shape
- * @return list of all subshapes
- */
- SVGRenderer.prototype.getAllSubShapes=function(shape){
- if(!shape)return null;
- else return shape.getElementsByTagName("path");
-
-
-
- };
- /**
- *get x:
- **/
- SVGRenderer.prototype.setX=function(shape,x){
- if(shape){
- var svg=shape.getElementsByTagName("svg")[0];
- if(svg){
- svg.setAttributeNS(null, 'x',x+'px');
- }
- }
-
- }
- /**
- * get the x value
- **/
- SVGRenderer.prototype.getX=function(shape,x){
- if(shape){
- var svg=shape.getElementsByTagName("svg")[0];
- if(svg){
- var x=svg.getAttribute("x");
- return x.split('px')[0];
- }
- }
-
- }
-
- SVGRenderer.prototype.getY=function(shape,x){
- if(shape){
- var svg=shape.getElementsByTagName("svg")[0];
- if(svg){
- var y=svg.getAttribute("y");
- return y.split('px')[0];
-
- }
- }
-
- }
- SVGRenderer.prototype.setY=function(shape,y){
- if(shape){
- var svg=shape.getElementsByTagName("svg")[0];
- if(svg){
- svg.setAttributeNS(null, 'y',y+'px');
- }
- }
-
- }
-
- /**
- *set the width, we take the template path and take every x element and multiply it with
- *the corresponding template.x/this.COORD_X
- **/
- SVGRenderer.prototype.setWidth=function(shape,width){
- if(shape){
- //first set the width in the svg element
- shape.getElementsByTagName("svg")[0].setAttributeNS(null,"width",width);
- //take tuples of paths and set width on them
- var paths=shape.getElementsByTagName("path");
- for (var i=0;i<(paths.length/2);i++){
- var index=i*2;
- this.setPathWidth(paths[index],paths[(index*1)+1],width);
- }
- }
- }
- /**
- * private method to set the path width
- *
- */
- SVGRenderer.prototype.setPathWidth=function(path,template,width){
- var pathSegList=path.pathSegList;
- var tempSegList=template.pathSegList;
- //these should match
- for(var i=0;i<pathSegList.numberOfItems;i++){
- var pathItem=pathSegList.getItem(i);
- var pathType=pathItem.pathSegTypeAsLetter;
- var tempItem=tempSegList.getItem(i);
- pathItem.x=(width)*(tempItem.x/this.COORD_X);
- if(pathType=='M'||pathType=='L')continue;
- if(pathType=='A'){
- pathItem.r1=(width)*(tempItem.r1/this.COORD_X);
- continue;
- }
- if(pathType=='C'){
- pathItem.x1=(width)*(tempItem.x1/this.COORD_X);
- pathItem.x2=(width)*(tempItem.x2/this.COORD_X);
- continue;
- }
-
- }
-
- }
-
- /**
- **set the height, we take the template path and take every x element and multiply it with
- *the corresponding template.x/this.COORD_X
- **/
- SVGRenderer.prototype.getWidth=function(shape,width){
- if(shape){
- return shape.getElementsByTagName("svg")[0].getAttributeNS(null,"width");
- }
- }
- /**
- *set the height, not sure if this is the correct way to access the matrix elements
- **/
- SVGRenderer.prototype.setHeight=function(shape,height){
- if(shape){
- //first set the width in the svg element
- shape.getElementsByTagName("svg")[0].setAttributeNS(null,"height",height);
- var paths=shape.getElementsByTagName("path");
- for (var i=0;i<(paths.length/2);i++){
- var index=i*2;
- this.setPathHeight(paths[index],paths[(index*1)+1],height);
- }
- }
- }
- /**
- * private method to set path height
- */
- SVGRenderer.prototype.setPathHeight=function(path,template,height){
- var pathSegList=path.pathSegList;
- var tempSegList=template.pathSegList;
- //these should match
- for(var i=0;i<pathSegList.numberOfItems;i++){
- var pathItem=pathSegList.getItem(i);
- var tempItem=tempSegList.getItem(i);
- var pathType=pathItem.pathSegTypeAsLetter;
- pathItem.y=(height)*(tempItem.y/this.COORD_Y);
- if(pathType=='M'||pathType=='L')continue;
- if(pathType=='A'){
- pathItem.r2=(height)*(tempItem.r2/this.COORD_Y);
- continue;
- }
- if(pathType=='C'){
- pathItem.y1=(height)*(tempItem.y1/this.COORD_Y);
- pathItem.y2=(height)*(tempItem.y2/this.COORD_Y);
- continue;
- }
- }
- }
-
-
-
- /**
- *get the height, not sure if this is the correct way to access the matrix elements
- **/
- SVGRenderer.prototype.getHeight=function(shape,height){
- if(shape){
- return shape.getElementsByTagName("svg")[0].getAttributeNS(null,"height");
- }
- }
-
- /**
- * get the rotation, the rotation is available set at the shape level itelf (g)
- **/
- SVGRenderer.prototype.getRotation=function(shape){
- if(!shape)return null;
- var item=shape.transform.baseVal.getItem(0);
- return item.angle;
-
- }
- /**
- *get the center x point of the shape
- **/
- SVGRenderer.prototype.getCenterX=function(shape){
- var box=this.bounds(shape);
- return (box.x*1)+((box.width*1)/2);
-
- }
- /**
- *get the center y point of the shape
- **/
- SVGRenderer.prototype.getCenterY=function(shape){
- var box=this.bounds(shape);
- return (box.y*1)+((box.height*1)/2);
- }
- /**
- * set the rotation to be the center of the shape
- **/
- SVGRenderer.prototype.setRotation=function(shape,angle){
- if(!shape)return null;
- var box=this.bounds(shape);
- var centerX=(box.x*1)+((box.width/2)*1);
- var centerY=(box.y*1)+((box.height/2)*1);
- var translate="rotate("+angle+","+ centerX+","+centerY+")";
- shape.setAttributeNS(null,'transform',translate);
- var item=shape.transform.baseVal.getItem(0);
- item.matrix.rotate(angle);
- }
-
- /**
- *a utility function to update rotation of the shape after a reset in x,y,width or height
- **/
- SVGRenderer.prototype.updateRotation=function(shape){
- var angle=this.getRotation(shape);
- this.setRotation(shape,angle);
-
- }
- /**
- *set the shape cursor
- **/
- SVGRenderer.prototype.setCursor=function(shape,cursor){
- if(cursor=='move'||cursor=='resize'||cursor=='crosshair')
- shape.style.cursor=cursor;
- else
- shape.style.cursor="URL("+cursor+"),auto";
-
-
- }
- /************************************END SHAPE ATTRIBUTE GETTERS AND SETTERS********************/
- /****************************BEGIN SHAPE MANIPULATION FUNCTIONS(MOVE,RESIZE,ROTATE)************/
- /**
- *rotate method called from editor
- **/
- SVGRenderer.prototype.rotate=function(shape,rotation){
- if(!rotation){
- rotation=0;
- }
- rotation=rotation%360;
- if(rotation<0){
- rotation=360+rotation;
- }
- this.setRotation(shape,rotation);
-
- }
- /**
- *respond to move keys
- **/
- SVGRenderer.prototype.fineMove = function(shape, move, isHorizontal) {
- //todo fix for line!!!
- if(!shape||this.isConnector(shape))return;
-
-
- if(isHorizontal){
- var left=this.getX(shape);
- left=(left*1)+move;
- this.setX(shape,left);
-
- }
- else{
- var top=this.getY(shape);
- top=(top*1)+move;
- this.setY(shape,top);
- }
- this.updateRotation(shape);
-
- };
- /**
- *respond to shift+R and shift+L
- **/
- SVGRenderer.prototype.fineRotateSelection=function(shape,angle){
- if(this.isConnector(shape))return;
- var rotation=this.getRotation(shape);
- if(!rotation)
- rotation=0;
- var rotation=rotation+angle;
- rotation=rotation%360;
- if(rotation<0){
- rotation=360+rotation;
-
- }
- this.setRotation(shape,rotation);
-
- };
- SVGRenderer.prototype.remove = function(shape) {
- if(shape)
- shape.parentNode.removeChild(shape);
- }
-
-
- /**
- * move the shape based on mouse movement
- **/
- SVGRenderer.prototype.move = function(shape, left, top) {
- this.setX(shape,left);
- this.setY(shape,top);
- this.updateRotation(shape);
-
- };
-
-
- /**
- *resize height:
- **/
-
-
-
- /**
- *this resize is called during draw,
- *after the draw is complete, subsequent resizes are handled by resizewidth or resizeheight
- **/
- SVGRenderer.prototype.resize = function(shape, fromX, fromY, toX, toY) {
- var deltaX = toX - fromX;
- var deltaY = toY - fromY;
-
- if (this.isConnector(shape)) {
- var type=this.getConnectorType(shape);
- if(type=='line'){
- this.setLineTo(shape,toX,toY);
- return;
- }
- else if (type=='ortho-line'){
- this.drawOrthoLine(shape,fromX,fromY,toX,toY);
- return;
- }
- else if (type=='curve-line'){
- this.drawCurveLine(shape,fromX,fromY,toX,toY,false);
- return;
- }
-
- }
-
- if (deltaX < 0) {
- this.setX(shape,toX);
- this.setWidth(shape,-deltaX );
-
- }
- else {
- this.setWidth(shape,deltaX);
-
- }
-
- if (deltaY < 0) {
- this.setY(shape,toY);
- this.setHeight(shape,-deltaY );
-
- }
- else {
- this.setHeight(shape,deltaY);
-
- }
- this.updateRotation(shape);
- };
-
- /*******************************************BEGIN CURVE CONNECTOR FUNCTIONS***********************************/
- SVGRenderer.prototype.drawCurveLine=function(shape,fromX,fromY,toX,toY,resize){
- var subject=this.getShapeSubject(shape);
- this.setLineFrom(shape,fromX,fromY);
- this.setLineTo(shape,toX,toY);
- if(!resize){
- var x1=Math.abs(fromX-toX);
- var y1=Math.abs(fromY-toY);
- var cx1=(fromX<toX)?(fromX*1)+(x1*(1/4)):(fromX*1)-(x1*(1/4));
- var cx2=(fromX<toX)?(toX*1)-(x1*(1/4)):(toX*1)+(x1*(1/4));
- var cy1=(fromY<toY)?(fromY*1)+(y1*(1/4)):(fromY*1)-(y1*(1/4));
- var cy2=(fromY<toY)?(toY*1)-(y1*(1/4)):(toY*1)+(y1*(1/4));
- this.setControl1(shape,cx1,cy1);
- this.setControl2(shape,cx2,cy2);
-
-
- }
- }
- /********************************************END CURVE CONNECTOR FUNCTIONS*************************************/
-
-
- /****************************END SHAPE MANIPULATION FUNCTIONS(MOVE,RESIZE,ROTATE)************/
- /**
- *command handler for this renderer
- **/
- SVGRenderer.prototype.editCommand = function(shape, cmd, value,zoom)
- {
- if (shape != null) {
- if(cmd=='sendBack'){
- this.sendToBack(shape);
- }
- else if(cmd=='bringFront'){
- this.bringToFront(shape);
- }
- else if (cmd == 'fillcolor') {
- this.setFillColor(shape,value);
- }
- else if (cmd == 'linecolor') {
- this.setLineColor(shape,value);
- }
- else if (cmd == 'linewidth') {
- this.setStrokeWidth(shape, parseInt(value) );
- }
- else if(cmd=='opacity'){
- this.setOpacity(shape,value);
- }
- else if(cmd=='shadow'){
- this.setShadow(shape,value);
- }
- else if(cmd=='gradient'){
- value=(value=='solid')?false:true;
- this.setLinearGradient(shape,value);
- }
- else if(cmd=='linestyle'){
- this.setLineStyle(shape,value);
- }
- else if (cmd=='linedashstyle'){
- this.setLineDashStyle(shape,value);
- }
- else if(cmd=='fontSize'||cmd=='fontFamily'||cmd=='bold'||cmd=='italic'||cmd=='fontColor'||cmd=='align'){
-
- var font=new Object();
- font.size='';
- font.family='';
- font.color='';
- font.align='';
- font.italics='';
- font.bold='';
- if(cmd=='fontSize'){
- font.size=value;
- this.setFont(shape,font,zoom);
- }
- else if(cmd=='fontFamily'){
- font.family=value;
- this.setFont(shape,font,zoom);
- }
- else if(cmd=='bold'){
- var oldFont=this.getFont(shape);
-
- if(oldFont.bold=='bold'){
- font.bold='normal';
- }
- else{
- font.bold='bold';
- }
- this.setFont(shape,font);
- }
-
- else if(cmd=='italic'){
- //debugger;
- var oldFont=this.getFont(shape);
- if(oldFont.italics=='italic'){
- font.italics='normal';
- }
- else{
- font.italics='italic';
- }
- this.setFont(shape,font);
- }
- else if(cmd=='fontColor'){
- font.color=value;
- this.setFont(shape,font);
- }
- else if(cmd=='align'){
- font.align=value;
- this.setFont(shape,font);
- }
-
- }
- }
- }
-
- /**
- *query handler for this renderer
- **/
- SVGRenderer.prototype.queryCommand = function(shape, cmd)
- {
- var result = '';
-
- if (shape != null) {
- if (cmd == 'fillcolor') {
- return this.getFillColor(shape);
- }
- else if (cmd == 'linecolor') {
- return this.getLineColor(shape);
- }
- else if (cmd == 'linewidth') {
- var width= this.getStrokeWidth(shape);
- if(width&&!width.indexOf('px')>=0)
- width=width+'px';
- return width;
- }
-
- else if(cmd=='font'){
-
- return this.getFont(shape);
- }
- else if(cmd=='linestyle'){
- return this.getLineStyle(shape);
- }
- else if (cmd=='linedashstyle'){
- return this.getLineDashStyle(shape);
- }
- else if(cmd=='opacity'){
- return this.getOpacity(shape);
- }
- else if(cmd=="gradient"){
- if(this.getLinearGradient(shape))return 'gradient';
- else return 'solid';
- }
- else if(cmd=="shadow"){
- return ""+this.getShadow(shape);
- }
-
- }
- return result;
- }
-
-
- /*********************************************TRACKER FUNCTIONS***************************************/
- /**
- *show the line tracker
- **/
- SVGRenderer.prototype.showLineTracker=function(shape){
- var parent=this.loadShape("tracker","g");
- this.svgRoot.appendChild(parent);
- parent.setAttributeNS(null,"id","tracker-group");
- this.updateLineTracker(shape,parent);
-
- return parent;
- }
-
- SVGRenderer.prototype.updateLineTracker=function(shape,parent){
- var oval=parent.getElementsByTagName("circle")[0];
- var type=this.getConnectorType(shape);
- if(type=='line'||type=='curve-line'){
- var x1=this.getConnectorFromX(shape);
- var y1=this.getConnectorFromY(shape);
- oval.setAttributeNS(null,"cx",x1);
- oval.setAttributeNS(null,"cy",y1);
- if(type=='curve-line'){
- var line=parent.getElementsByTagName("line")[0];
- line.setAttributeNS(null,'x1',x1);
- line.setAttributeNS(null,'y1',y1);
- }
- }
- else if (type=='ortho-line'){
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- var x1=points.getItem(0).x;
- var y1=points.getItem(0).y;
- oval.setAttributeNS(null,"cx",x1);
- oval.setAttributeNS(null,"cy",y1);
- }
- oval.style.zIndex=this.maxIndex+1;
- oval=parent.getElementsByTagName("circle")[1];
- if(type=='line'||type=='curve-line'){
- var x2=this.getConnectorToX(shape);
- var y2=this.getConnectorToY(shape);;
- oval.setAttributeNS(null,"cx",x2);
- oval.setAttributeNS(null,"cy",y2);
- if(type=='curve-line'){
- var line=parent.getElementsByTagName("line")[1];
- line.setAttributeNS(null,'x1',x2);
- line.setAttributeNS(null,'y1',y2);
- }
-
- }
- else if (type=='ortho-line'){
- var polyline=this.getShapeSubject(shape);
- var points=polyline.points;
- var length=points.numberOfItems;
- if(length==0)return;
- var x2=points.getItem(length-1).x;
- var y2=points.getItem(length-1).y;
- oval.setAttributeNS(null,"cx",x2);
- oval.setAttributeNS(null,"cy",y2);
- }
- if(type=='curve-line'){
- var control1=this.getControl1(shape);
- oval=parent.getElementsByTagName("circle")[2];
- oval.setAttributeNS(null,"cx",control1.x);
- oval.setAttributeNS(null,"cy",control1.y);
- oval.style.visibility="visible";
- var line=parent.getElementsByTagName("line")[0];
- line.setAttributeNS(null,'x2',control1.x);
- line.setAttributeNS(null,'y2',control1.y);
-
- var control2=this.getControl2(shape);
- oval=parent.getElementsByTagName("circle")[3];
- oval.setAttributeNS(null,"cx",control2.x);
- oval.setAttributeNS(null,"cy",control2.y);
- oval.style.visibility="visible";
- line=parent.getElementsByTagName("line")[1];
- line.setAttributeNS(null,'x2',control2.x);
- line.setAttributeNS(null,'y2',control2.y);
- }
-
- oval.style.zIndex=this.maxIndex+1;
- //now set the tracker
- }
- /**
- *load the tracker and show it, we may want to cache the tracker if it becomes a performance issue
- **/
- SVGRenderer.prototype.showTracker = function(shape) {
- if(!shape)return
- var tracker = $('tracker-group');
- if (tracker) {
- this.remove(tracker);
- }
- if(this.isConnector(shape))
- {
- return this.showLineTracker(shape);
- }
-
- tracker=this.loadShape("tracker-group","g");
-
- this.svgRoot.appendChild(tracker);
- this.updateTracker(shape);
- return tracker;
- }
- /**
- *update the tracker if its already present
- **/
- SVGRenderer.prototype.updateTracker=function(shape){
- if(!shape)return;
- var tracker=$('tracker-group');
- if(tracker){
- if(this.isConnector(shape))
- return this.updateLineTracker(shape,tracker);
- }
- if(!$('tracker-group'))return this.showTracker(shape);
-
- var box=this.bounds(shape);
- var trackerGroup=$('tracker-group');
- var tracker=$('tracker');
- var width=(parseInt(box.width)+10);
- var height=(parseInt(box.height)+10);
- var x=(parseInt(box.x)-5);
- var y=(parseInt(box.y)-5);
- var centerX=(x*1)+(width/2);
- var centerY=(y*1)+(height/2);
- var translate="rotate("+box.rotation+","+ centerX+","+centerY+")";
- trackerGroup.setAttributeNS(null,'transform',translate);
- tracker.setAttributeNS(null,'width',width+'px');
- tracker.setAttributeNS(null,'height',height+'px');
- tracker.parentNode.setAttributeNS(null,'x',x+'px');
- tracker.parentNode.setAttributeNS(null,'y',y+'px');
- $('resize-left').setAttributeNS(null,'y',(box.height/2)+'px');
- $('resize-top').setAttributeNS(null,'x',(box.width/2)+'px');
- var resizeBottom=$('resize-bottom');
- resizeBottom.setAttributeNS(null,'x',(box.width/2)+'px');
- resizeBottom.setAttributeNS(null,'y',(parseInt(box.height)+5)+'px');
- var resizeRight=$('resize-right');
- resizeRight.setAttributeNS(null,'x',(parseInt(box.width)+5)+'px');
- resizeRight.setAttributeNS(null,'y',(box.height/2)+'px');
- $('tracker-rotate').setAttributeNS(null,'cx',((box.width/2)+5)+'px');
- //set the rotation
-
-
-
-
- }
- /**************************************END TRACKER FUNCTIONS*****************************************/
- /***************************************BEGIN TEXT FUNCTIONS****************************************/
- /**
- *note:some text functions are inherited from abstractRenderer (see vmlrenderer.js)
- **/
- /**
- *this method should be called only after getShapeText has been called by the editor to save the text
- */
- SVGRenderer.prototype.clearShapeText=function(shape){
- var nodes=shape.getElementsByTagName("text");
- var nodeArray=$A(nodes);
- for(var i=0;i<nodeArray.length;i++){
- var node=nodeArray[i];
- if(node.id=="text:normal"||node.id=="text:newline")
- this.remove(node);
- }
- if(this.isConnector(shape)){
- var bgShape=shape.getElementsByTagName("rect");
- if(bgShape.length>0){
- this.hideConnectorBackground(bgShape[0]);
- }
- }
- }
-
-
- /**
- * basically call to handleTextLinePositioning for svg, since text is handled in the same manner for connectors and shapes,
- * the vml versio is implemented
- * @see vmlrenderer.js#handleConnectorTextLinePositioning
- */
- SVGRenderer.prototype.handleConnectorTextLinePositioning=function(height,width,x,y,center,fontSize,lines,shapeFont,shape){
-
- return this.handleTextLinePositioning(height,width,x,y,center,fontSize,lines,shapeFont,shape);
-
- }
- /**
- *create the text elements and handle text positioning
- **/
- SVGRenderer.prototype.handleTextLinePositioning=function(height,width,x,y,center,fontSize,lines,shapeFont,shape){
- var centerY=(y*1)+(height*1)/2;
- var align;
- if(shapeFont.align=='center'){
- align=(x*1)+(width/2);
- }
- else if(shapeFont.align=='left'){
- align=(x*1)+(10*1)
- }
- else{
- align=(x*1)+(width-10);
- }
-
- var shapeArray=new Array();
- for (var i=center;i>0;i--){
- var lineTopMargin=(centerY)+((fontSize*1.1)*(i-center));
- lineTopMargin=(lineTopMargin*1)+((fontSize)/4);
- shapeArray[shapeArray.length]=this.createTextShape(lines[i-1],true,lineTopMargin,null,align,null,shapeFont,shape);
- }
- for (var i=center;i<lines.length;i++){
- var lineTopMargin=(centerY)+((fontSize*1.1)*(i+1-center));
- lineTopMargin=(lineTopMargin*1)+((fontSize)/4);
- shapeArray[shapeArray.length]=this.createTextShape(lines[i],true,lineTopMargin,null,align,null,shapeFont,shape);
- }
- return shapeArray;
-
- }
- /**
- * set the dimensions of the background shape for the connector text
- * todo, fix visibility here...
- */
- SVGRenderer.prototype.handleConnectorTextBackgroundPositioning=function(shape,rect,text){
- var bgShape=this.getConnectorBackgroundShape(shape);
- shape.getElementsByTagName("svg")[0].appendChild(bgShape);
- if(text&&trim(text).length>0){
- bgShape.setAttributeNS(null,"fill","white");
- bgShape.setAttributeNS(null,"x",rect.x);
- bgShape.setAttributeNS(null,"y",rect.y);
- bgShape.setAttributeNS(null,"width",rect.width);
- bgShape.setAttributeNS(null,"height",rect.height);
- }
- else{
-
- this.hideConnectorBackground(bgShape);
- }
-
- }
- /**
- * hide the connector background, this comes handy when we want to clear the connector text (during moves, resize etc)
- * or when the text is empty
- * @param background shape for the connector
- */
- SVGRenderer.prototype.hideConnectorBackground=function(bgShape){
- if(bgShape){
- bgShape.setAttributeNS(null,"x",0);
- bgShape.setAttributeNS(null,"y",0);
- bgShape.setAttributeNS(null,"width",0);
- bgShape.setAttributeNS(null,"height",0);
- }
- }
- /**
- * a utility function to create a text set, sometimes we may need to create a dummy text set (which can hold the
- *default values for font etc. (see setShapeText)in which case
- * we need to pass the shape.id as the type in the line object and texpathok=false
- */
- SVGRenderer.prototype.createTextShape=function(line,textpathok,lineTopMargin,lineHeightMargin,start,end,shapeFont,containerShape){
- var shape=null;
-
- if(!textpathok){
- shape=containerShape.ownerDocument.getElementById("text:template"+line.type);
-
- }
- if(textpathok||!shape){
-
- shape=this.createElement("text",this.svgNamespace);
- if(textpathok)
- shape.id="text:"+line.type;
- else
- shape.id="text:template"+line.type;
- }
- shape.setAttributeNS(null,"x",start);
- shape.setAttributeNS(null,"y",lineTopMargin);
- shape.style.position="absolute";
- shape.setAttributeNS(null,"fill",shapeFont.color);
- shape.setAttributeNS(null,"font-size",shapeFont.size);
- shape.setAttributeNS(null,"font-weight",shapeFont.bold);
- shape.setAttributeNS(null,"font-family",shapeFont.family);
- shape.setAttributeNS(null,"font-style",shapeFont.italics);
- //directive to preserve any space
- shape.setAttribute("xml:space","preserve");
- var textAnchor="middle";
- if(shapeFont.align=='left'){
- textAnchor="start";
- }
- else if(shapeFont.align=='right'){
- textAnchor="end";
- }
- shape.setAttributeNS(null,"text-anchor",textAnchor);
- shape.textContent=line.text;
- return shape;
-
- }
-
- /**
- *utility function to set the fontsize,fontcolor,fontfamily,fontdecoration(bold,italics,underline) and textalign for a given shape
- * if you want to selectively set something e.g size, then only pass size in the font leaving the rest of the stuff as null
- */
- SVGRenderer.prototype.setFont=function(shape,font,zoom){
-
- var dummyText=this.getShapeText(shape);
- //if this is null, then dummy text does not exist
- //so we have to create one and then we leave
- if(!dummyText){
- this.fillUpFont(font);
- this.setShapeText(shape," ",font,true,null,zoom);
- return;
- }
- //we already have text...now we can start, get the text shapes first
- var textList=shape.getElementsByTagName("text");
- var shapeFont=this.getFont(shape);
- //if font size changes, we really need to redo the spacing etc.
- if(font.size!=''&&(font.size!=shapeFont.size)){
-
- this.clearShapeText(shape);
- this.setShapeText(shape,dummyText,font,true,shapeFont,zoom);
-
- }
- //otherwise we will set things individually, no need to create things
- if(font.color!=''){
- for(var i=0;i<textList.length;i++){
- textList[i].setAttributeNS(null,"fill",font.color);
-
- }
- }
- //now set the text path specific properties
- if(font.family!=''){
- for(var i=0;i<textList.length;i++){
- textList[i].setAttributeNS(null,"font-family",font.family);
- }
- }
- if(font.bold!=''){
- for(var i=0;i<textList.length;i++){
- textList[i].setAttributeNS(null,"font-weight",font.bold);
- }
- }
- if(font.italics!=''){
- for(var i=0;i<textList.length;i++){
- textList[i].setAttributeNS(null,"font-style",font.italics);
- }
- }
- if(font.align!=''){
- var align;
- //pass dummytext and zoom for connectors
- var rect=this.getTextBounds(shape,dummyText,zoom);
- var x=rect['x'];
- var width=rect['width'];
- if(font.align=='center'){
- align=(x*1)+(width/2);
- }
- else if(font.align=='left'){
- align=(x*1)+(10*1)
- }
- else{
- align=(x*1)+(width-10);
- }
- var textAnchor="middle";
- if(font.align=='left'){
- textAnchor="start";
- }
- else if(font.align=='right'){
- textAnchor="end";
- }
- for(var i=0;i<textList.length;i++){
- textList[i].setAttributeNS(null,"x",align);
- textList[i].setAttributeNS(null,"text-anchor",textAnchor);
-
-
- }
-
- }
- }
-
- /**
- *this method will pull out the font from the dummyText and then report it back
- **/
-
- SVGRenderer.prototype.getFont=function(shape){
-
- var font=new Object();
- font.size='';
- font.family='';
- font.color='';
- font.align='';
- font.italics='';
- font.bold='';
- //for backward compatibility. after 0.2 we will use "text:template";
- var element=document.getElementById("text:dummy"+shape.id);;
- if(!element){
- element=document.getElementById("text:template"+shape.id);
- }
- if(!element)
- return font;
- else{
-
-
- font.color=element.getAttributeNS(null,"fill");
-
- font.family=element.getAttributeNS(null,"font-family");
-
- font.size=element.getAttributeNS(null,"font-size");
-
- font.bold=element.getAttributeNS(null,"font-weight");
-
- font.italics=element.getAttributeNS(null,"font-style");;
- //todo for align!!!
- var align=element.getAttributeNS(null,"text-anchor");
- if(align=='middle')
- align='center';
- else if(align=='end')
- align='right';
- else
- align='left';
- font.align=align;
-
- }
- return font;
-
- }
-
-
-
- SVGRenderer.prototype.getMarkup = function() {
- return this.container.innerHTML;
- }
- /**incase of svg the selection source comes back as path which resides in g/svg/path,
- **in order to return g we need to climb 2 levels
- **/
- SVGRenderer.prototype.getShapeFromEventSource=function(source){
-
- if(source){
- if(source.tagName=='text')
- return source.parentNode;
- else
- return source.parentNode.parentNode;
- }
- }
-
- /**
- *append an attribute to the page cumulate draw specific
- **/
- SVGRenderer.prototype.appendPageAttribute=function(div,attribute){
- if(div){
- var svg=div.getElementsByTagName("svg")[0];
- svg.appendChild(attribute);
- }
-
- }
- /**
- *get the actual data from within the richdraw div
- **/
- SVGRenderer.prototype.getRealData=function(){
- var xml=this.svgRoot.xml;
- var parser=new DOMParser(true);
- parser.preserveWhiteSpace=true;
- return parser.parseFromString(xml, "application/xml");
- }
-
- /**
- *return the response as a valid xml document
- **/
- SVGRenderer.prototype.getValidDocumentFromResponse=function(response){
- var parser=new DOMParser(true);
- parser.preserveWhiteSpace=true;
- return parser.parseFromString(response, "application/xml");
- }
-
- /**
- *open the objects in .fmd file
- **/
- SVGRenderer.prototype.open=function(div){
- var nodes=div.getElementsByTagName("g");
- nodes=$A(nodes);
- for(var i=0;i<nodes.length;i++){
- this.svgRoot.appendChild(nodes[i]);
- }
- }
-
-